package com.ft.oa.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.ft.oa.domain.sys.SysDept;
import com.ft.oa.domain.sys.SysUser;
import com.ft.oa.domain.sys.SysUserDept;
import com.ft.oa.mapper.sys.SysDeptMapper;
import com.ft.oa.mapper.sys.SysUserDeptMapper;
import com.ft.oa.mapper.sys.SysUserMapper;
import com.ft.oa.service.sys.SysDeptService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysDeptServiceImpl implements SysDeptService {

    @Resource
    private SysDeptMapper sysDeptMapper;
    @Resource
    private SysUserDeptMapper userDeptMapper;
    @Resource
    private SysUserMapper sysUserMapper;

    @Override
    @Transactional
    public void add(SysDept dept) {
        dept.setCreateTime(LocalDateTime.now());
        sysDeptMapper.insert(dept);
    }

    @Override
    public List<SysDept> list() {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysDept::getDel, false);

        List<SysDept> list = sysDeptMapper.selectList(wrapper);
        return list;
    }

    @Override
    public List<SysDept> userDepts(Long id) {
        QueryWrapper<SysUserDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysUserDept::getUserId, id);
        List<SysUserDept> sysUserDepts = userDeptMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(sysUserDepts)){
            return new ArrayList<>();
        }
        List<SysDept> sysDepts = sysDeptMapper.selectBatchIds(sysUserDepts.stream().map(SysUserDept::getDeptId).collect(Collectors.toList()));
        List<SysDept> result = sysDepts.stream().filter(e -> e.getDel().equals(Boolean.FALSE)).collect(Collectors.toList());

        return result;
    }

    @Override
    public List<SysDept> tree() {
        QueryWrapper<SysDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysDept::getDel, false);

        List<SysDept> deptList = sysDeptMapper.selectList(wrapper);

        Map<Integer, List<SysDept>> groupByPid = deptList.stream()
                .collect(Collectors.groupingBy(SysDept::getPid));

        deptList.forEach(
                e -> {
                    if(groupByPid.containsKey(e.getId())){
                        e.setChildren(groupByPid.get(e.getId()));
                    }
                }
        );

        List<SysDept> tree = groupByPid.get(0);

        return tree;
    }

    @Override
    @Transactional
    public void del(Integer id) {
        LambdaUpdateChainWrapper<SysDept> wrapper = new LambdaUpdateChainWrapper<SysDept>(sysDeptMapper);
        boolean update = wrapper.eq(SysDept::getId, id)
                .set(SysDept::getDel, true)
                .set(SysDept::getDeleteTime, LocalDateTime.now())
                .update();
    }

    @Override
    public void removeUsers(SysDept dept) {
        QueryWrapper<SysUserDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysUserDept::getDeptId, dept.getId())
                .in(SysUserDept::getUserId, dept.getUserIds());
        int delete = userDeptMapper.delete(wrapper);

    }

    @Override
    public List<SysUser> users(SysDept sysDept) {
        QueryWrapper<SysUserDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysUserDept::getDeptId, sysDept.getId());
        List<SysUserDept> sysUserDepts = userDeptMapper.selectList(wrapper);
        if(CollectionUtils.isEmpty(sysUserDepts)){
            return new ArrayList<>();
        }
        List<SysUser> users = sysUserMapper.selectBatchIds(sysUserDepts.stream().map(SysUserDept::getUserId).collect(Collectors.toSet()));
        users.forEach(e->e.setPassword(""));
        return users;
    }

    @Override
    @Transactional
    public void addUsers(SysDept dept) {
        QueryWrapper<SysUserDept> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(SysUserDept::getDeptId, dept.getId());
        int delete = userDeptMapper.delete(wrapper);

        dept.getUserIds().stream()
                .map(userId -> new SysUserDept(userId, dept.getId()))
                .forEach(e -> userDeptMapper.insert(e));
    }

    @Override
    @Transactional
    public void edit(SysDept dept) {
        LambdaUpdateChainWrapper<SysDept> wrapper = new LambdaUpdateChainWrapper<SysDept>(sysDeptMapper);

        boolean update = wrapper.eq(SysDept::getId, dept.getId())
                .set(SysDept::getName, dept.getName())
                .set(SysDept::getInfo, dept.getInfo())
                .set(SysDept::getCostRate, dept.getCostRate())
                .set(SysDept::getUpdateTime, LocalDateTime.now())
                .update();

    }
}
